import 'package:flutter/foundation.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:shared_preferences/shared_preferences.dart';

class BluetoothStore with ChangeNotifier, DiagnosticableTreeMixin {

  // 存储蓝牙特征
  late BluetoothDevice? _device;
  BluetoothCharacteristic? _characteristic;

  BluetoothDevice? get device => _device;
  BluetoothCharacteristic? get characteristic => _characteristic;

  setDevice(BluetoothDevice? value) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    _device = value;
    if (value == null) {
      return prefs.remove('remoteId');
    }
    prefs.setString('remoteId', value.remoteId.toString());
  }

  setCharacteristic(BluetoothCharacteristic? value) async {
    _characteristic = value;
    notifyListeners();
    SharedPreferences prefs = await SharedPreferences.getInstance();
    if (value == null) {
      return prefs.remove('characteristicId');
    }
    prefs.setString('characteristicId', value.uuid.toString());
  }

  Future<String> sendDataInChunks(Uint8List data, int chunkSize) async {
    int totalChunks = (data.length + chunkSize - 1) ~/ chunkSize; // 计算总包数

    for (int i = 0; i < totalChunks; i++) {
      int start = i * chunkSize;
      int end = start + chunkSize > data.length ? data.length : start + chunkSize;
      Uint8List chunk = data.sublist(start, end); // 获取数据块

      // 发送数据块
      try{
        await onWritePressed(chunk);
      } catch (e) {
        throw '写入错误 $e';
      }
    }
    return '数据包发送成功!';
  }


  Future<bool> connectStatus() async {
    try {
      await device?.connect();
      return true;
    } catch (e) {
      return false;
    }
  }

  // 写入方法
  Future<String> onWritePressed(bytes) async {

    if (_characteristic == null) {
      throw '蓝牙未连接！！！';
    }

    try {
      await _characteristic!.write(bytes, withoutResponse: _characteristic!.properties.writeWithoutResponse);
      if (_characteristic!.properties.read) {
        await _characteristic!.read();
      }
    return '蓝牙写入成功';
    } catch (e) {
      debugPrint('e-------------$e');
      throw '蓝牙写入失败！！！';
    }
  }

  // 自动连接
  Future<String> autoConnect() async {
    try{
      SharedPreferences prefs = await SharedPreferences.getInstance();
      String remoteId = prefs.getString('remoteId') ?? '';
      var device = BluetoothDevice.fromId(remoteId);
      await connectDevice(device);
      return '自动连接成功！！！';
    } catch(e) {
      debugPrint('e-------------$e');
      throw '当前页面没有可用的有效蓝牙！！';
    }
  }

  // 连接设备
  Future<String> connectDevice(device) async {

    List<BluetoothService> services;

    try {
      await device.connect();
    } catch (e) {
      throw '连接失败,请检查连接设备是否正常!';
    }

    // 获取服务
    try {
      services = await device.discoverServices();
    } catch(e) {
      throw '连接设备没有可用的服务!';
    }

    BluetoothCharacteristic? characteristic;
    try{
      SharedPreferences prefs = await SharedPreferences.getInstance();
      String uuid = prefs.getString('characteristicId') ?? '';
      String remoteId = prefs.getString('remoteId') ?? '';

      characteristic = findCharacteristics(services, uuid: remoteId == device.remoteId.toString() ? uuid : '');

      if (characteristic == null) {
        throw '连接设备没有可以写入数据的特征!';
      }

    }catch(e) {
      throw '连接设备没有可以写入数据的特征!';
    }

    setDevice(device);
    setCharacteristic(characteristic);

    return '连接成功!';
  }

  // 断开连接
  Future<void> disconnect() async {
    await device?.disconnect();
    setDevice(null);
    setCharacteristic(null);
  }

  // 查找可打印的特征 新增查找指定特征
  BluetoothCharacteristic? findCharacteristics(List<BluetoothService> services, { String uuid = '', int index = 0}) {

    if (index >= services.length) {
      return null;
    }

    try{
      BluetoothCharacteristic? characteristic = services[index].characteristics.firstWhere((characteristic){
        if (uuid.isNotEmpty) {
          return characteristic.uuid.toString() == uuid;
        }
        return characteristic.properties.write;
      });

      return characteristic;
    } catch(e) {
      return findCharacteristics(services, index: index + 1, uuid: uuid);
    }

  }


  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties
      ..add(ObjectFlagProperty('device', device))
      ..add(ObjectFlagProperty('characteristic', characteristic));
  }
}

